package com.neusoft.databus.sap.ssh;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.util.Arrays;

import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import sshd.shell.springboot.autoconfiguration.SshdShellCommand;

@Component
@SshdShellCommand(value = "socket", description = "tcp communication test.  Type 'socket' for supported subcommands\"")
public class SocketCommand {

    @SshdShellCommand(value = "tcp", description = "tcp communication test. Usage: socket tcp 192.168.0.122:8765 string_value [so_timeout]")
    public String buildInfo(String arg) throws IOException {

        if (StringUtils.isEmpty(arg)) {
            return "illegal command";
        }
        final String[] arguments = arg.split("\\s+");
        if (arguments.length < 2) {
            return "illegal command";
        }

        if (arguments[0].split(":").length != 2) {
            return "illegal command";
        }

        final SocketAddress address =
                new InetSocketAddress(arguments[0].split(":")[0], Integer.valueOf(arguments[0].split(":")[1]));
        final Socket socket = new Socket();
        try {
            socket.setTrafficClass(0x04 | 0x10);
            socket.setKeepAlive(true);
            socket.setTcpNoDelay(true);
            socket.setSendBufferSize(1024);
            socket.setReceiveBufferSize(1024);

            socket.connect(address, 3000);
            if (arguments.length > 2) {
                final int soTimeout = Integer.valueOf(arguments[2]);
                socket.setSoTimeout(soTimeout);
            } else {
                socket.setSoTimeout(3000);
            }

            socket.getOutputStream().write(arguments[1].getBytes());
            socket.getOutputStream().flush();

            final byte[] buf = new byte[2048];
            int n = -1;
            try {
                n = socket.getInputStream().read(buf, 0, buf.length);
            } catch (final SocketTimeoutException e) {
                return "read time out";
            }
            if (n == -1) {
                return "no data";
            }
            final byte[] data = Arrays.copyOf(buf, n);
            return new String(data);
        } catch (final Exception e) {
            return e.getMessage();
        } finally {
            try {
                socket.close();
            } catch (final IOException e) {
            }
        }
    }

}
